Xceed DataGrid for Silverlight provides synchronous and asynchronous XML spreadsheet format (xmlss) exporting capabilities with the resulting documents supported by Excel 2002 and up as well as by the Microsoft Office Web Components Spreadsheet Component. Data can also be exported to the comma-separate value (CSV) format, which is compatible with a wide variety of applications.
Exporting to XML Spreadsheet and CVS Formats
Through the XmlssExporter and CsvExporter classes, the entire content of a grid, or a specific selection of data items, can be exported to an XMLSS or CSV-formatted stream, which can then be written to disk, the clipboard, etc.
In order to begin an asynchronous export operation, the BeginExport method must be called specifying the stream to which the data items will be exported, the data items to export, as well as the AsyncCallback that will be called once the export operation completes.If the BeginExport method returns an IAsyncResult that indicates that the completed operation synchronously (i.e., IsCompleted is true), then the EndExport method can be called immediately after BeginExport. If the IAsyncResult indicates that the export operation is not completed (i.e., asynchronous operation), then the EndExport method will need to be called in the callback. In either case, the stream must be closed and disposed of after the EndExport method has been called.
The CancelExport method allows the export operation to be canceled at any time during the operation; however, rather than discarding the data that has already been exported, it will call the end-export callback, resulting in a valid, albeit partial, document.
|
Because only one export operation can be executed at a time, it is recommended to disable any buttons or controls that launch export operations until the current operation completes. |
|
The XmlssExporter and CsvExporter classes also expose the Export method, which can be used to synchronously export data items; however, it can only be used with a non-asynchronous data source (e.g., local list) and the UI will be "frozen" until the operation returns. It is highly recommended to only use this method if a small amount of data items are to be exported. |
The IncludeColumnHeaders property indicates whether column headers will be exported alongside the data (by default, true). By default, the column titles (see Title property) are displayed in the column headers. If the UseFieldNamesInHeaders property is set to true, the column field names will be used instead.
The XmlssExporter class also defines the UseFixedHeaderRow property, which indicates whether the row that displays the column headers remains fixed and always visible above the exported data items.
How the exported data is formatted when using the CsvExporter class is determined by the CsvFormatSettings through which various format settings can be defined. The DateTimeFormat, FloatingPointFormat, and NumericFormat properties define how date-time, floating-point, and numeric values are formatted, respectively. The NewLine property defines the string that will be used at the end of each row, including any headers, to indicate a new line. Through the Separator property, the character that will be used to separate the fields in a row can be defined, while the TextDelimiter property defines the character used to delimit the value of a string, date, or numeric field if it contains a white space.
Asynchronous exporting to XML spreadsheet format
<sldg:DataGridControl x:Name="sldgDataGridControl"
ItemsSource="{Binding Path=Orders}">
<sldg:DataGridControl.Resources>
<local:InverseBooleanConverter x:Key="inverseBooleanConverter"/>
</sldg:DataGridControl.Resources>
<sldg:DataGridControl.GroupDescriptions>
<sldg:DataGridGroupDescription PropertyName="ShipCountry"/>
</sldg:DataGridControl.GroupDescriptions>
<sldg:DataGridControl.Columns>
<sldg:Column FieldName="ShipCountry"
Title="COUNTRY"/>
</sldg:DataGridControl.Columns>
<sldg:DataGridControl.FixedFooters>
<StackPanel>
<Button Click="ExportAll_Click"
Content="Export All"
IsEnabled="{Binding Path=IsExporting, Converter={StaticResource inverseBooleanConverter}}"/>
<Button Content="Export Selected"
Click="ExportSelected_Click"
IsEnabled="{Binding Path=IsExporting, Converter={StaticResource inverseBooleanConverter}}"/>
<Button Content="Export Custom"
Click="ExportCustomSelection_Click"
IsEnabled="{Binding Path=IsExporting, Converter={StaticResource inverseBooleanConverter}}"/>
<Button Content="Cancel Export"
Click="CancelExport_Click"/>
</StackPanel>
</sldg:DataGridControl.FixedFooters>
</sldg:DataGridControl>
Private Sub ExportAll_Click( ByVal sender As Object, ByVal e As RoutedEventArgs )
Me.ExportData( Nothing )
End Sub
Private Sub ExportSelected_Click( ByVal sender As Object, ByVal e As RoutedEventArgs )
Me.ExportData( Me.sldgDataGridControl.SelectedRanges )
End Sub
Private Sub ExportCustomSelection_Click( ByVal sender As Object, ByVal e As RoutedEventArgs )
Dim selectionRange As New SelectionRange( NewSortDescription() { New SortDescription( "ShipCity", ListSortDirection.Ascending ) }, Nothing, Nothing )
selectionRange.StartRangeInfos.Add( "ShipCity", "L" )
selectionRange.StartRangeInfos.IsInclusive = True
selectionRange.EndRangeInfos.ToEnd()
Me.ExportData( New SelectionRange() { selectionRange } )
End Sub
Private m_exporter As XmlssExporter
Private Sub ExportData( ByVal selectionRanges As IList( Of SelectionRange) )
Me.IsExporting = True
Dim saveFileDiag As New SaveFileDialog()
saveFileDiag.Filter = "XML Spreadsheet (*.xml)|*.xml|All files (*.*)|*.*"
m_exporter = New XmlssExporter( Me.sldgDataGridControl )
m_exporter.IncludeColumnHeaders = True
m_exporter.UseFieldNamesInHeaders = False
m_exporter.UseFixedHeaderRow = False
If( saveFileDiag.ShowDialog().GetValueOrDefault() ) Then
Dim stream As Stream = saveFileDiag.OpenFile()
Dim asyncResult As IAsyncResult = m_exporter.BeginExport( stream, selectionRanges, New AsyncCallback( AddressOf Me.EndExportToFile ), Nothing )
' BeginExport() is already completed, call EndExport right away
If asyncResult.IsCompleted Then
stream = m_exporter.EndExport( asyncResult )
stream.Close()
stream.Dispose()
End If
Else
Me.IsExporting = False
End If
End Sub
Private Sub EndExportToFile( ByVal asyncResult As IAsyncResult )
' BeginExport() was completed synchronously and will be treated in ExportData().
If asyncResult.CompletedSynchronously Then
Return
End If
Dim stream As Stream= m_exporter.EndExport( asyncResult )
stream.Close()
stream.Dispose()
Me.IsExporting = False
End Sub
Private Sub CancelExport_Click( ByVal sender As object, ByVal e As RoutedEventArgs )
' When CancelExport is called, the EndExport callback will follow in which you must call
' the EndExport method and close and dispose of the stream. Calling CancelExport will result
' in a valid, albeit partial, exported document.
m_exporter.CancelExport()
End Sub
' This dependency property was created so that buttons (or any other control) that launch
' an export operation could bind to it and be disabled during the export operation.
' If an attempt is made to launch an export operation while one is already in progress,
' and exception will be thrown.
Public Shared ReadOnly IsExportingProperty As DependencyProperty = DependencyProperty.Register( "IsExporting", GetType( Boolean ), GetType( MainPage ), Nothing )
Property Property IsExporting As Boolean
Get
Return CBool( GetValue( IsExportingProperty ) )
End Get
Set
SetValue( IsExportingProperty, value )
End Set
End Property
private void ExportAll_Click( object sender, RoutedEventArgs e )
{
this.ExportData( null );
}
private void ExportSelected_Click( object sender, RoutedEventArgs e )
{
this.ExportData( this.sldgDataGridControl.SelectedRanges );
}
private void ExportCustomSelection_Click( object sender, RoutedEventArgs e )
{
SelectionRange selectionRange = new SelectionRange( new SortDescription[] { new SortDescription( "ShipCity", ListSortDirection.Ascending ) }, null, null );
selectionRange.StartRangeInfos.Add( "ShipCity", "L" );
selectionRange.StartRangeInfos.IsInclusive = true;
selectionRange.EndRangeInfos.ToEnd();
this.ExportData( new SelectionRange[] { selectionRange } );
}
private XmlssExporter m_exporter;
private void ExportData( IList<SelectionRange> selectionRanges )
{
this.IsExporting = true;
SaveFileDialog saveFileDiag = new SaveFileDialog();
saveFileDiag.Filter = "XML Spreadsheet (*.xml)|*.xml|All files (*.*)|*.*";
m_exporter = new XmlssExporter( this.sldgDataGridControl );
m_exporter.IncludeColumnHeaders = true;
m_exporter.UseFieldNamesInHeaders = false;
m_exporter.UseFixedHeaderRow = false;
if( saveFileDiag.ShowDialog().GetValueOrDefault() )
{
Stream stream = saveFileDiag.OpenFile();
IAsyncResult asyncResult = m_exporter.BeginExport( stream, selectionRanges, new AsyncCallback( this.EndExportToFile ), null );
// BeginExport() is already completed, call EndExport right away
if( asyncResult.IsCompleted )
{
stream = m_exporter.EndExport( asyncResult );
stream.Close();
stream.Dispose();
}
}
else
{
this.IsExporting = false;
}
}
private void EndExportToFile( IAsyncResult asyncResult )
{
// BeginExport() was completed synchronously and will be treated in ExportData().
if( asyncResult.CompletedSynchronously )
return;
Stream stream = m_exporter.EndExport( asyncResult );
stream.Close();
stream.Dispose();
this.IsExporting = false;
}
private void CancelExport_Click( object sender, RoutedEventArgs e )
{
// When CancelExport is called, the EndExport callback will follow in which you must call
// the EndExport method and close and dispose of the stream. Calling CancelExport will result
// in a valid, albeit partial, exported document.
m_exporter.CancelExport();
}
// This dependency property was created so that buttons (or any other control) that launch
// an export operation could bind to it and be disabled during the export operation.
// If an attempt is made to launch an export operation while one is already in progress,
// and exception will be thrown.
public static readonly DependencyProperty IsExportingProperty = DependencyProperty.Register( "IsExporting", typeof( Boolean ), typeof( MainPage ), null );
public bool IsExporting
{
get
{
return ( bool )GetValue( IsExportingProperty );
}
set
{
SetValue( IsExportingProperty, value );
}
}
Synchronous exporting to the clipboard using CSV format
<sldg:DataGridControl x:Name="sldgDataGridControl"
ItemsSource="{Binding Path=People}">
<sldg:DataGridControl.FixedFooters>
<Button Content="Copy To Clipboard"
Click="CsvExport_Click"/>
</sldg:DataGridControl.FixedFooters>
</sldg:DataGridControl>
Private Sub CsvExport_Click( ByVal sender As Object, ByVal e As RoutedEventArgs )
If Me.sldgDataGridControl.SelectedRanges.Count > 0 Then
Me.ExportToCsv( Me.sldgDataGridControl.SelectedRanges )
End If
End Sub
Private Sub ExportToCsv( ByVal selectionRanges As IList( Of SelectionRange ) )
Dim csvExporter As New CsvExporter( Me.sldgDataGridControl )
csvExporter.IncludeColumnHeaders = False
'Set properties that are null by default.
csvExporter.FormatSettings.Culture = CultureInfo.CurrentCulture
csvExporter.FormatSettings.Separator = ';'
Dim stream AS new MemoryStream()
' Call the synchronous method, so the items can be pasted to the clipboard within a user-initiated event.
csvExporter.Export( stream, selectionRanges )
Me.CopyItemsToClipboard( stream )
stream.Close()
stream.Dispose()
End Sub
Private Sub CopyItemsToClipboard( ByVal stream As Stream )
Dim copyboardText As String = String.Empty
Dim encoding As Encoding = Encoding.Unicode
Dim buffer As New Byte( 32768 )
Dim bytesRead As Integer = 0
stream.Position = 0
' Get the content of the exported stream as a string.
While( ( bytesRead = stream.Read( buffer, 0, buffer.Length ) ) > 0 )
copyboardText += encoding.GetString( buffer, 0, bytesRead )
End While
' Copy it to the clipboard.
Clipboard.SetText( copyboardText )
End Sub
private void CsvExport_Click( object sender, RoutedEventArgs e )
{
if( this.sldgDataGridControl.SelectedRanges.Count > 0 )
this.ExportToCsv( this.sldgDataGridControl.SelectedRanges );
}
private void ExportToCsv( IList<SelectionRange> selectionRanges )
{
CsvExporter csvExporter = new CsvExporter( this.sldgDataGridControl );
csvExporter.IncludeColumnHeaders = false;
//Set properties that are null by default.
csvExporter.FormatSettings.Culture = CultureInfo.CurrentCulture;
csvExporter.FormatSettings.Separator = ';';
using( Stream stream = new MemoryStream() )
{
// Call the synchronous method, so the items can be pasted to the clipboard within a user-initiated event.
csvExporter.Export( stream, selectionRanges );
this.CopyItemsToClipboard( stream );
stream.Close();
}
}
private void CopyItemsToClipboard( Stream stream )
{
string copyboardText = string.Empty;
Encoding encoding = Encoding.Unicode;
byte[] buffer = new byte[ 32768 ];
int bytesRead = 0;
stream.Position = 0;
// Get the content of the exported stream as a string.
while( ( bytesRead = stream.Read( buffer, 0, buffer.Length ) ) > 0 )
{
copyboardText += encoding.GetString( buffer, 0, bytesRead );
}
// Copy it to the clipboard.
Clipboard.SetText( copyboardText );
}
|
When exporting data items to the clipboard for the first item, a prompt will be displayed by Silverlight asking if access to the clipboard is to be granted for the application.
|